home *** CD-ROM | disk | FTP | other *** search
/ Isometric Game Programming with DirectX 7.0 / Isometric Game Programming.iso / source / chapter6 / isohex6_3a / isohex6_3a.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-22  |  12.7 KB  |  506 lines

  1. /*****************************************************************************
  2. IsoHex6_3A.cpp
  3. Ernest S. Pazera
  4. 22MAY2000
  5. Start a WIN32 Application Workspace, add in this file
  6. Needs ddraw.lib and dxguid.lib
  7. Needs GDICanvas.h/cpp
  8. *****************************************************************************/
  9.  
  10. //////////////////////////////////////////////////////////////////////////////
  11. //INCLUDES
  12. //////////////////////////////////////////////////////////////////////////////
  13. #define WIN32_LEAN_AND_MEAN  
  14.  
  15. #include <windows.h>   
  16. #include "GDICanvas.h"
  17. #include "ddraw.h"
  18.  
  19. //////////////////////////////////////////////////////////////////////////////
  20. //DEFINES
  21. //////////////////////////////////////////////////////////////////////////////
  22. //name for our window class
  23. #define WINDOWCLASS "ISOHEX6"
  24. //title of the application
  25. #define WINDOWTITLE "IsoHex 6-2"
  26.  
  27. //////////////////////////////////////////////////////////////////////////////
  28. //PROTOTYPES
  29. //////////////////////////////////////////////////////////////////////////////
  30. bool Prog_Init();//game data initalizer
  31. void Prog_Loop();//main game loop
  32. void Prog_Done();//game clean up
  33.  
  34. //enumeration functions
  35. HRESULT WINAPI EnumModesCallbackCount(LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext);
  36. HRESULT WINAPI EnumModesCallbackList(LPDDSURFACEDESC2 lpDDSurfaceDesc,LPVOID lpContext);
  37.  
  38. //////////////////////////////////////////////////////////////////////////////
  39. //GLOBALS
  40. //////////////////////////////////////////////////////////////////////////////
  41. HINSTANCE hInstMain=NULL;//main application handle
  42. HWND hWndMain=NULL;//handle to our main window
  43. //IDirectDraw7 Pointer
  44. LPDIRECTDRAW7 lpdd=NULL;
  45. //display mode structure
  46. struct DisplayMode
  47. {
  48.     DWORD dwWidth;
  49.     DWORD dwHeight;
  50.     DWORD dwBPP;
  51. };
  52. //display mode enumeration variables
  53. DWORD dwDisplayModeCount=0;
  54. DisplayMode* DisplayModeList=NULL;
  55.  
  56. //gdicanvas
  57. CGDICanvas gdicBall;
  58.  
  59. //surfaces
  60. LPDIRECTDRAWSURFACE7 lpddsPrime=NULL;
  61. LPDIRECTDRAWSURFACE7 lpddsBack=NULL;
  62. LPDIRECTDRAWSURFACE7 lpddsBall=NULL;
  63.  
  64. //size of the display
  65. DWORD dwDisplayWidth=0;
  66. DWORD dwDisplayHeight=0;
  67.  
  68. //position of the ball
  69. POINT ptBallPosition[2];
  70. POINT ptLastPosition[2][2];
  71. //velocity of the ball
  72. POINT ptBallVelocity[2];
  73.  
  74. //////////////////////////////////////////////////////////////////////////////
  75. //WINDOWPROC
  76. //////////////////////////////////////////////////////////////////////////////
  77. LRESULT CALLBACK TheWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
  78. {
  79.     //which message did we get?
  80.     switch(uMsg)
  81.     {
  82.     case WM_KEYDOWN:
  83.         {
  84.             //check for escape key
  85.             if(wParam==VK_ESCAPE)
  86.             {
  87.                 DestroyWindow(hWndMain);
  88.             }
  89.  
  90.             return(0);//handled message
  91.         }break;
  92.     case WM_DESTROY://the window is being destroyed
  93.         {
  94.  
  95.             //tell the application we are quitting
  96.             PostQuitMessage(0);
  97.  
  98.             //handled message, so return 0
  99.             return(0);
  100.  
  101.         }break;
  102.     case WM_PAINT://the window needs repainting
  103.         {
  104.             //a variable needed for painting information
  105.             PAINTSTRUCT ps;
  106.             
  107.             //start painting
  108.             HDC hdc=BeginPaint(hwnd,&ps);
  109.  
  110.             /////////////////////////////
  111.             //painting code would go here
  112.             /////////////////////////////
  113.  
  114.             //end painting
  115.             EndPaint(hwnd,&ps);
  116.                         
  117.             //handled message, so return 0
  118.             return(0);
  119.         }break;
  120.     }
  121.  
  122.     //pass along any other message to default message handler
  123.     return(DefWindowProc(hwnd,uMsg,wParam,lParam));
  124. }
  125.  
  126.  
  127. //////////////////////////////////////////////////////////////////////////////
  128. //WINMAIN
  129. //////////////////////////////////////////////////////////////////////////////
  130. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
  131. {
  132.     //assign instance to global variable
  133.     hInstMain=hInstance;
  134.  
  135.     //create window class
  136.     WNDCLASSEX wcx;
  137.  
  138.     //set the size of the structure
  139.     wcx.cbSize=sizeof(WNDCLASSEX);
  140.  
  141.     //class style
  142.     wcx.style=CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  143.  
  144.     //window procedure
  145.     wcx.lpfnWndProc=TheWindowProc;
  146.  
  147.     //class extra
  148.     wcx.cbClsExtra=0;
  149.  
  150.     //window extra
  151.     wcx.cbWndExtra=0;
  152.  
  153.     //application handle
  154.     wcx.hInstance=hInstMain;
  155.  
  156.     //icon
  157.     wcx.hIcon=LoadIcon(NULL,IDI_APPLICATION);
  158.  
  159.     //cursor
  160.     wcx.hCursor=LoadCursor(NULL,IDC_ARROW);
  161.  
  162.     //background color
  163.     wcx.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
  164.  
  165.     //menu
  166.     wcx.lpszMenuName=NULL;
  167.  
  168.     //class name
  169.     wcx.lpszClassName=WINDOWCLASS;
  170.  
  171.     //small icon
  172.     wcx.hIconSm=NULL;
  173.  
  174.     //register the window class, return 0 if not successful
  175.     if(!RegisterClassEx(&wcx)) return(0);
  176.  
  177.     //create main window
  178.     hWndMain=CreateWindowEx(0,WINDOWCLASS,WINDOWTITLE, WS_POPUP | WS_VISIBLE,0,0,320,240,NULL,NULL,hInstMain,NULL);
  179.  
  180.     //error check
  181.     if(!hWndMain) return(0);
  182.  
  183.     //if program initialization failed, then return with 0
  184.     if(!Prog_Init()) return(0);
  185.  
  186.     //message structure
  187.     MSG msg;
  188.  
  189.     //message pump
  190.     for(;;)    
  191.     {
  192.         //look for a message
  193.         if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  194.         {
  195.             //there is a message
  196.  
  197.             //check that we arent quitting
  198.             if(msg.message==WM_QUIT) break;
  199.             
  200.             //translate message
  201.             TranslateMessage(&msg);
  202.  
  203.             //dispatch message
  204.             DispatchMessage(&msg);
  205.         }
  206.  
  207.         //run main game loop
  208.         Prog_Loop();
  209.     }
  210.     
  211.     //clean up program data
  212.     Prog_Done();
  213.  
  214.     //return the wparam from the WM_QUIT message
  215.     return(msg.wParam);
  216. }
  217.  
  218. //////////////////////////////////////////////////////////////////////////////
  219. //INITIALIZATION
  220. //////////////////////////////////////////////////////////////////////////////
  221. bool Prog_Init()
  222. {
  223.     //error code 
  224.     HRESULT hr;
  225.  
  226.     //initialize the dd pointer
  227.     hr=DirectDrawCreateEx(NULL,(void**)&lpdd,IID_IDirectDraw7,NULL);
  228.  
  229.     //example for error handling
  230.     if(FAILED(hr))
  231.     {
  232.         //initialization failed
  233.         return(false);
  234.     }
  235.  
  236.     //set the cooperative level
  237.     lpdd->SetCooperativeLevel(hWndMain,DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT);
  238.  
  239.     //enumerate the displaymodes
  240.     dwDisplayModeCount=0;
  241.  
  242.     lpdd->EnumDisplayModes(0,NULL,NULL,EnumModesCallbackCount);
  243.  
  244.     DisplayModeList=new DisplayMode[dwDisplayModeCount];
  245.     dwDisplayModeCount=0;
  246.  
  247.     lpdd->EnumDisplayModes(0,NULL,NULL,EnumModesCallbackList);
  248.  
  249.     //pick a display mode
  250.     DisplayMode TestMode;
  251.     TestMode.dwWidth=0;
  252.     TestMode.dwHeight=0;
  253.     TestMode.dwBPP=0;
  254.     DWORD index;
  255.     bool found=false;
  256.  
  257.     for(index=0;(index<dwDisplayModeCount);index++)
  258.     {
  259.         if(DisplayModeList[index].dwBPP==16)
  260.         {
  261.             if(DisplayModeList[index].dwWidth>TestMode.dwWidth)
  262.             {
  263.                 TestMode.dwWidth=DisplayModeList[index].dwWidth;
  264.                 TestMode.dwHeight=DisplayModeList[index].dwHeight;
  265.                 TestMode.dwBPP=DisplayModeList[index].dwBPP;
  266.                 found=true;
  267.             }
  268.         }
  269.     }
  270.  
  271.     if(!found)
  272.     {
  273.         return(false);
  274.     }
  275.  
  276.     //set the display mode
  277.     hr=lpdd->SetDisplayMode(TestMode.dwWidth,TestMode.dwHeight,TestMode.dwBPP,0,0);
  278.     //keep display width and height in global variables
  279.     dwDisplayWidth=TestMode.dwWidth;
  280.     dwDisplayHeight=TestMode.dwHeight;
  281.  
  282.     //create the primary surface with a single back buffer
  283.     //clear out a DDSURFACEDESC2
  284.     DDSURFACEDESC2 ddsd;
  285.     memset(&ddsd,0,sizeof(DDSURFACEDESC2));
  286.     ddsd.dwSize=sizeof(DDSURFACEDESC2);
  287.  
  288.     //set the flags for primary surface
  289.     ddsd.dwFlags=DDSD_BACKBUFFERCOUNT | DDSD_CAPS;
  290.     //set back buffer count
  291.     ddsd.dwBackBufferCount=1;
  292.     //set caps
  293.     ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
  294.  
  295.     //create the surface
  296.     lpdd->CreateSurface(&ddsd,&lpddsPrime,NULL);
  297.  
  298.     //clear out a DDSCAPS2
  299.     DDSCAPS2 ddsCaps;
  300.     memset(&ddsCaps,0,sizeof(DDSCAPS2));
  301.  
  302.     //set the caps
  303.     ddsCaps.dwCaps=DDSCAPS_BACKBUFFER;
  304.  
  305.     //retrieve back buffer
  306.     lpddsPrime->GetAttachedSurface(&ddsCaps,&lpddsBack);
  307.  
  308.     //do an initial clearing out of the back buffer
  309.     //clean out a DDBLTFX
  310.     DDBLTFX ddbltfx;
  311.     memset(&ddbltfx,0,sizeof(DDBLTFX));
  312.     ddbltfx.dwSize=sizeof(DDBLTFX);
  313.  
  314.     //set the fill color to black
  315.     ddbltfx.dwFillColor=0;
  316.  
  317.     //do a color fill
  318.     lpddsBack->Blt(NULL,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
  319.  
  320.     //load in the ball image
  321.     gdicBall.Load(NULL,"IsoHex6_3.bmp");
  322.  
  323.     //create an offscreen surface to contain the ball
  324.     //clear out ddsd
  325.     memset(&ddsd,0,sizeof(DDSURFACEDESC2));
  326.     ddsd.dwSize=sizeof(DDSURFACEDESC2);
  327.  
  328.     //set ddsd flags
  329.     ddsd.dwFlags=DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
  330.  
  331.     //set width and height
  332.     ddsd.dwWidth=gdicBall.GetWidth();
  333.     ddsd.dwHeight=gdicBall.GetHeight();
  334.  
  335.     //set caps
  336.     ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN;
  337.  
  338.     //create surface
  339.     lpdd->CreateSurface(&ddsd,&lpddsBall,NULL);
  340.  
  341.     //grab dc from offscreen surface
  342.     HDC hdcSurf;
  343.     lpddsBall->GetDC(&hdcSurf);
  344.  
  345.     //blit ball to surface
  346.     BitBlt(hdcSurf,0,0,gdicBall.GetWidth(),gdicBall.GetHeight(),gdicBall,0,0,SRCCOPY);
  347.  
  348.     //release dc
  349.     lpddsBall->ReleaseDC(hdcSurf);
  350.  
  351.     //create a black color key
  352.     DDCOLORKEY ddck;
  353.     ddck.dwColorSpaceLowValue=0;
  354.     ddck.dwColorSpaceHighValue=0;
  355.  
  356.     //assign color key to ball surface
  357.     lpddsBall->SetColorKey(DDCKEY_SRCBLT,&ddck);
  358.  
  359.     //initialize ball position and velocity
  360.     ptBallPosition[0].x=0;
  361.     ptBallPosition[0].y=0;
  362.     ptLastPosition[0][0].x=0;
  363.     ptLastPosition[0][0].y=0;
  364.     ptLastPosition[0][1].x=0;
  365.     ptLastPosition[0][1].y=0;
  366.     ptBallPosition[1].x=0;
  367.     ptBallPosition[1].y=0;
  368.     ptLastPosition[1][0].x=0;
  369.     ptLastPosition[1][0].y=0;
  370.     ptLastPosition[1][1].x=0;
  371.     ptLastPosition[1][1].y=0;
  372.  
  373.     ptBallVelocity[0].x=4;
  374.     ptBallVelocity[0].y=2;
  375.     ptBallVelocity[1].x=2;
  376.     ptBallVelocity[1].y=4;
  377.  
  378.     return(true);//return success
  379. }
  380.  
  381. //////////////////////////////////////////////////////////////////////////////
  382. //CLEANUP
  383. //////////////////////////////////////////////////////////////////////////////
  384. void Prog_Done()
  385. {    
  386.     //clean up ball surface
  387.     if(lpddsBall)
  388.     {
  389.         lpddsBall->Release();
  390.         lpddsBall=NULL;
  391.     }
  392.         
  393.     //clean up primary surface(this will clean up the back buffer, also)
  394.     if(lpddsPrime)
  395.     {
  396.         lpddsPrime->Release();
  397.         lpddsPrime=NULL;
  398.         lpddsBack=NULL;
  399.     }
  400.  
  401.     //clean up the dd pointer
  402.     if(lpdd)
  403.     {
  404.         lpdd->Release();
  405.         lpdd=NULL;
  406.     }
  407.  
  408.     //clean up gdicanvas
  409.     gdicBall.Destroy();
  410.  
  411.     //get rid of enumeration stuff
  412.     delete [] DisplayModeList;
  413. }
  414.  
  415. //////////////////////////////////////////////////////////////////////////////
  416. //MAIN GAME LOOP
  417. //////////////////////////////////////////////////////////////////////////////
  418. void Prog_Loop()
  419. {
  420.     int index;
  421.  
  422.     for(index=0;index<2;index++)
  423.     {
  424.  
  425.     //set up rectangle for filling
  426.     RECT rcFill;
  427.     SetRect(&rcFill,ptLastPosition[index][0].x,ptLastPosition[index][0].y,ptLastPosition[index][0].x+gdicBall.GetWidth(),ptLastPosition[index][0].y+gdicBall.GetHeight());
  428.  
  429.     //set up a ddbltfx
  430.     DDBLTFX ddbltfx;
  431.     memset(&ddbltfx,0,sizeof(DDBLTFX));
  432.     ddbltfx.dwSize=sizeof(DDBLTFX);
  433.  
  434.     //set up a color fill of black
  435.     ddbltfx.dwFillColor=0;
  436.  
  437.     //blt the color fill to the back buffer
  438.     lpddsBack->Blt(&rcFill,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
  439.     }
  440.  
  441.     for(index=0;index<2;index++)
  442.     {
  443.     //set up source and destination rects for blitting the ball
  444.     RECT rcSrc;
  445.     RECT rcDst;
  446.  
  447.     SetRect(&rcSrc,0,0,gdicBall.GetWidth(),gdicBall.GetHeight());
  448.     CopyRect(&rcDst,&rcSrc);
  449.     OffsetRect(&rcDst,ptBallPosition[index].x,ptBallPosition[index].y);
  450.  
  451.     //blit the ball
  452.     lpddsBack->Blt(&rcDst,lpddsBall,&rcSrc,DDBLT_WAIT | DDBLT_KEYSRC, NULL);
  453.  
  454.     //copy current position of ball to old position
  455.     ptLastPosition[index][0]=ptLastPosition[index][1];
  456.     ptLastPosition[index][1]=ptBallPosition[index];
  457.  
  458.     //move the ball
  459.     ptBallPosition[index].x+=ptBallVelocity[index].x;
  460.     ptBallPosition[index].y+=ptBallVelocity[index].y;
  461.  
  462.     //bounds checking
  463.     //left side
  464.     if(ptBallPosition[index].x<=0) ptBallVelocity[index].x=abs(ptBallVelocity[index].x);
  465.     //top side
  466.     if(ptBallPosition[index].y<=0) ptBallVelocity[index].y=abs(ptBallVelocity[index].y);
  467.     //right side
  468.     if(ptBallPosition[index].x>=(int)dwDisplayWidth-gdicBall.GetWidth()) ptBallVelocity[index].x=-abs(ptBallVelocity[index].x);
  469.     //bottom side
  470.     if(ptBallPosition[index].y>=(int)dwDisplayHeight-gdicBall.GetHeight()) ptBallVelocity[index].y=-abs(ptBallVelocity[index].y);
  471.     }
  472.     //flip surfaces
  473.     lpddsPrime->Flip(NULL,DDFLIP_WAIT);
  474. }
  475.  
  476. //enumeration-count
  477. HRESULT WINAPI EnumModesCallbackCount(
  478.   LPDDSURFACEDESC2 lpDDSurfaceDesc,  
  479.   LPVOID lpContext                   
  480. )
  481. {
  482.     //increment the count variable
  483.     dwDisplayModeCount++;
  484.  
  485.     //continue the enumeration
  486.     return(DDENUMRET_OK);
  487. }
  488.  
  489. //enumeration-list
  490. HRESULT WINAPI EnumModesCallbackList(
  491.   LPDDSURFACEDESC2 lpDDSurfaceDesc,  
  492.   LPVOID lpContext                   
  493. )
  494. {
  495.     //copy applicable information to the list
  496.     DisplayModeList[dwDisplayModeCount].dwWidth=lpDDSurfaceDesc->dwWidth;
  497.     DisplayModeList[dwDisplayModeCount].dwHeight=lpDDSurfaceDesc->dwHeight;
  498.     DisplayModeList[dwDisplayModeCount].dwBPP=lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount;
  499.  
  500.     //increment the count variable
  501.     dwDisplayModeCount++;
  502.  
  503.     //continue the enumeration
  504.     return(DDENUMRET_OK);
  505. }
  506.